home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 9 / CDACTUAL9.iso / share / Dos / VARIOS / pascal / SWAG9605.DDD / 0051_Pascal ScanF like 'C' function.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-05-31  |  3.0 KB  |  108 lines

  1. {
  2. >Format is really a good function for use on output and it corresponds roughly
  3. >to the printf function in C, but I really need the corresponding input
  4. >function as well (scanf etc)
  5. >
  6. >does anyone know of such a function? I would hate to spend the time
  7. >reinventing the wheel, when I could be concentrating on other things.
  8.  
  9. Here's my implementation of scanf:
  10.  
  11. --------------------------------------------------------------------------}
  12.  
  13. function sscanf(Input, Format : PChar; var ArgList) : PChar;
  14. type
  15.   WordPtr = ^word;
  16.   LongPtr = ^longint;
  17.   PCharPtr = ^PChar;
  18. var
  19.   DelimPos : PChar;
  20.   ArgPtr : PChar;
  21.   n : longint;
  22.   FmtCmd : char;
  23.   code : integer;
  24.   LongCmd : boolean;
  25.   LenStr : string[8];
  26.   MaxLen : integer;
  27. begin
  28.   sscanf := nil;
  29.   ArgPtr := addr(ArgList);
  30.   if (Format = nil) then Exit;
  31.   while (Format^ <> #0) do begin
  32.     if (Input = nil) or (Input^ = #0) then Exit; { ***ERROR }
  33.     if Format^ = '%' then begin
  34.       inc(Format);
  35.       FmtCmd := Format^;
  36.  
  37.       if FmtCmd in ['0'..'9'] then begin
  38.         LenStr := '';
  39.         repeat
  40.           LenStr := LenStr + FmtCmd;
  41.           inc(Format);
  42.           FmtCmd := Format^;
  43.         until not (FmtCmd in ['0'..'9']);
  44.         if LenStr <> '' then begin
  45.           Val(LenStr, MaxLen, code);
  46.           if code <> 0 then Exit;
  47.         end;
  48.       end else
  49.         MaxLen := $7FFF;
  50.  
  51.       if FmtCmd = 'l' then begin
  52.         LongCmd := true;
  53.         inc(Format);
  54.         FmtCmd := Format^;
  55.       end else
  56.         LongCmd := false;
  57.  
  58.       case FmtCmd of
  59.         'c' : begin
  60.           ArgPtr^ := Input^;
  61.           inc(ArgPtr, 2);
  62.         end;
  63.         'd','i','u','s','*' : begin
  64.           { look for delimiter }
  65.           DelimPos := StrScan(Input, (Format+1)^);
  66.           if DelimPos <> nil then begin
  67.             if (DelimPos-Input > MaxLen) then Exit;
  68.             DelimPos^ := #0; { zero delimiter }
  69.           end;
  70.  
  71.           if FmtCmd = 's' then begin
  72.             if PCharPtr(ArgPtr)^ = nil then { if dest. string is NIL }
  73.               PCharPtr(ArgPtr)^ := StrNew(Input) { then allocate a new one }
  74.             else
  75.               StrCopy(PCharPtr(ArgPtr)^, Input); { else copy to dest buffer }
  76.           end else
  77.             if FmtCmd <> '*' then
  78.               Val(Input, n, code);
  79.  
  80.           if DelimPos <> nil then DelimPos^ := (Format+1)^; { set it back }
  81.           case FmtCmd of
  82.             's' : inc(ArgPtr, 4);
  83.             '*' : ; { dummy }
  84.           else
  85.             if code <> 0 then Exit; { could not convert }
  86.             if LongCmd then begin
  87.               LongPtr(ArgPtr)^ := n;
  88.               inc(ArgPtr, 4);
  89.             end else begin
  90.               WordPtr(ArgPtr)^ := LongRec(n).Lo;
  91.               inc(ArgPtr, 2);
  92.             end;
  93.           end;
  94.           Input := DelimPos; { move input pointer to delimiter }
  95.         end;
  96.       else
  97.         Exit;
  98.       end;
  99.       inc(Format);
  100.     end else begin
  101.       if Input^ <> Format^ then Exit;
  102.       inc(Format);
  103.       inc(Input);
  104.     end;
  105.   end;
  106.   sscanf := Input;
  107. end;
  108.